package com.zl.ots.lambda;

import com.zl.ots.utils.NamingConverterUtil;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.lang.reflect.Field;
import java.lang.reflect.Modifier;

/**
 * 字段配置
 */
@Data
@Slf4j
public class LambdaSett {
    /**
     * 字段
     */
    private Field field;
    /**
     * 字段名
     */
    private String filedName;

    private Class implClass;

    public LambdaSett(SerializedLambda lambda, String filedName) {
        this.implClass = lambda.getImplClass();
        field = getAccessibleField(lambda.getImplClass(), filedName);
        this.filedName = NamingConverterUtil.camelToSnake(filedName);
    }

    public static Field getAccessibleField(Class<?> clazz, final String fieldName) {
        for (Class<?> superClass = clazz; superClass != Object.class; superClass = superClass.getSuperclass()) {
            try {
                Field field = superClass.getDeclaredField(fieldName);
                makeAccessible(field);
                return field;
            } catch (NoSuchFieldException e) {//NOSONAR
                // Field不在当前类定义,继续向上转型
                throw new RuntimeException(e.getMessage());
            }
        }
        log.error("获取字段fieldName失败");
        throw new RuntimeException("获取字段fieldName失败");
    }

    public static void makeAccessible(Field field) {
        if ((!Modifier.isPublic(field.getModifiers()) || !Modifier.isPublic(field.getDeclaringClass().getModifiers()) || Modifier
                .isFinal(field.getModifiers())) && !field.isAccessible()) {
            field.setAccessible(true);
        }
    }
}
